#include "evaluationFunction.h"

const double Evaluation::EMPTY_VALUE = 0.0;

const double Evaluation::BLACK_PAWN_VALUE = 100;
const double Evaluation::BLACK_KNIGHT_VALUE = 300;const double Evaluation::BLACK_BISHOP_VALUE = 325;
const double Evaluation::BLACK_ROOK_VALUE = 500;
const double Evaluation::BLACK_QUEEN_VALUE = 900;
const double Evaluation::BLACK_KING_VALUE = 1000000;
const double Evaluation::WHITE_PAWN_VALUE = -100;
const double Evaluation::WHITE_KNIGHT_VALUE = -300;
const double Evaluation::WHITE_BISHOP_VALUE = -325;
const double Evaluation::WHITE_ROOK_VALUE = -500;
const double Evaluation::WHITE_QUEEN_VALUE = -900;
const double Evaluation::WHITE_KING_VALUE = -1000000;
        
const double Evaluation::mob1 = 0.0;
const double Evaluation::mob2 = 0.7;
const double Evaluation::mob3 = 1.9;
const double Evaluation::mob4 = 2.6;
        
        //static const double mobility[8][8];

// Used for raise values of pieces held in the middle.
const double Evaluation::mobility[8][8] = 
{ 
    mob1, mob1, mob1, mob1, mob1, mob1, mob1, mob1,
    mob1, mob2, mob2, mob2, mob2, mob2, mob2, mob1,
    mob1, mob2, mob3, mob3, mob3, mob3, mob2, mob1, 
    mob1, mob2, mob3, mob4, mob4, mob3, mob2, mob1,
    mob1, mob2, mob3, mob4, mob4, mob3, mob2, mob1,
    mob1, mob2, mob3, mob3, mob3, mob3, mob2, mob1,
    mob1, mob2, mob2, mob2, mob2, mob2, mob2, mob1, 
    mob1, mob1, mob1, mob1, mob1, mob1, mob1, mob1
};

// Public constructor.
Evaluation::Evaluation(const GameState &state)
{
    this->evaluateState(state);   
}

// Private constructor, only for internal use.
Evaluation::Evaluation(double oldValue)
{
    evaluationValue = -oldValue;
}

// Evaluation function.
void Evaluation::evaluateState(const GameState& state)
{     
    double result = 0.0;
    double m = 0.0;
    
    if(state.computeIsLosingState())
    {
        this->evaluationValue = -1000000000;
        return;   
    }
    
    
	 if(state.isEnemyUnderCheck)
	 	result += 40.0;
	 else if(state.isPlayerUnderCheck)
	   result -= 40.0;   
    
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            m += mobility[i][j] * state.attackInfo[0][i][j];
            
            switch( state.board[i][j] )
            {
                case BLACK_PAWN:
                    result +=  BLACK_PAWN_VALUE;
                    break;
                case WHITE_PAWN:
                    result +=  WHITE_PAWN_VALUE;
                    break;
                case BLACK_KNIGHT:
                    result +=  BLACK_KNIGHT_VALUE;
                    break;
                case WHITE_KNIGHT:
                    result +=  WHITE_KNIGHT_VALUE;
                    break;
                case BLACK_BISHOP:
                    result +=  BLACK_BISHOP_VALUE;
                    break;
                case WHITE_BISHOP:
                    result +=  WHITE_BISHOP_VALUE;
                    break;
                case BLACK_ROOK:
                    result +=  BLACK_ROOK_VALUE;
                    break;
                case WHITE_ROOK:
                    result +=  WHITE_ROOK_VALUE;
                    break;
                case BLACK_QUEEN:
                    result +=  BLACK_QUEEN_VALUE;
                    break;
                case WHITE_QUEEN:
                    result +=  WHITE_QUEEN_VALUE;
                    break;
                case BLACK_KING:
                    result +=  BLACK_KING_VALUE;
                    break;
                case WHITE_KING:
                    result +=  WHITE_KING_VALUE;
                    break;
                case EMPTY:
                    result += EMPTY_VALUE;
                    break;
            }
        }
    }
    if(state.round == WHITE)
    {
        this->evaluationValue = -result + m;
    }
    else
    {
        this->evaluationValue = result + m;
    }
}

bool Evaluation::operator<(const Evaluation& second) const
{
    if(this->evaluationValue < second.evaluationValue)
        return true;   
    else
        return false;
}

Evaluation operator-(const Evaluation& old)
{
    return Evaluation(old.evaluationValue);   
}
